import socket
import threading
from datetime import datetime
import json
import time
import tkinter as tk
from tkinter import messagebox

class NetworkManager:
    def __init__(self, root, message_display, status_var, timestamp_var):
        self.root = root
        self.message_display = message_display
        self.status_var = status_var
        self.timestamp_var = timestamp_var
        self.connected = False
        self.socket = None
        self.on_receive_message = None
        
        # 超时配置
        self.CONNECT_TIMEOUT = 3.0
        self.HANDSHAKE_TIMEOUT = 3.0
        self.DATA_SEND_TIMEOUT = 3.0
        self.RESPONSE_TIMEOUT = 3.0

    def connect_to_server(self, ip, port):
        if not port.isdigit():
            self.status_var.set("错误: 端口必须是数字")
            return False
            
        port = int(port)
        
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.settimeout(self.CONNECT_TIMEOUT)
            self.status_var.set(f"正在连接到 {ip}:{port}...")
            self.socket.connect((ip, port))
            self.connected = True
            self.status_var.set(f"已连接: {ip}:{port}")
            
            # 启动接收线程
            threading.Thread(target=self.receive_messages, daemon=True).start()
            return True
        except socket.timeout:
            self.status_var.set(f"连接超时: 服务器 {ip}:{port} 未响应 (超时 {self.CONNECT_TIMEOUT} 秒)")
        except ConnectionRefusedError:
            self.status_var.set(f"连接被拒绝: 服务器 {ip}:{port} 未运行或端口错误")
        except socket.gaierror:
            self.status_var.set(f"域名解析错误: 无法解析 IP 地址 {ip}")
        except Exception as e:
            self.status_var.set(f"连接失败: {str(e)}")
        finally:
            if not self.connected and self.socket:
                self.socket.close()
                self.socket = None
        return False

    def disconnect_from_server(self):
        try:
            if self.socket:
                self.socket.close()
                self.status_var.set("已断开连接")
        except Exception:
            pass
        finally:
            self.socket = None
            self.connected = False

    def send_message(self, message):
        if not self.connected:
            return False
            
        try:
            self.socket.sendall(message.encode('utf-8'))
            return True
        except Exception as e:
            self.status_var.set(f"发送失败: {str(e)}")
            self.disconnect_from_server()
            return False

    def receive_messages(self):
        while self.connected:
            try:
                data = self.socket.recv(1024)
                if not data:
                    break
                message = data.decode('utf-8')
                self.root.after_idle(self.update_message_display, message)
                
                if self.on_receive_message:
                    self.root.after_idle(self.on_receive_message, message)
            except socket.timeout:
                continue
            except ConnectionResetError:
                try:
                    if hasattr(self, 'root') and self.root and hasattr(self, 'status_var') and self.status_var:
                        self.root.after_idle(lambda: self.status_var.set("连接被服务器重置"))
                except Exception:
                    pass
                break
            except Exception as e:
                try:
                    if hasattr(self, 'root') and self.root and hasattr(self, 'status_var') and self.status_var:
                        error_msg = f"接收错误: {str(e)}"
                        self.root.after_idle(lambda msg=error_msg: self.status_var.set(msg))
                except Exception:
                    pass
                break
        
        if self.connected:
            self.disconnect_from_server()

    def display_sent_message(self, message):
        self.message_display.config(state=tk.NORMAL)
        if self.timestamp_var.get():
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            self.message_display.insert(tk.END, f"[{timestamp}] ", "timestamp")
            self.message_display.insert(tk.END, "我: ", "sent")
            self.message_display.insert(tk.END, f"{message}\n", "sent")
        else:
            self.message_display.insert(tk.END, f"我: {message}\n", "sent")
        self.message_display.config(state=tk.DISABLED)

    def update_message_display(self, message):
        self.message_display.config(state=tk.NORMAL)
        if self.timestamp_var.get():
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            self.message_display.insert(tk.END, f"[{timestamp}] ", "timestamp")
            self.message_display.insert(tk.END, "服务器: ", "received")
            self.message_display.insert(tk.END, f"{message}\n", "received")
        else:
            self.message_display.insert(tk.END, f"服务器: {message}\n", "received")
        self.message_display.config(state=tk.DISABLED)
        self.message_display.see(tk.END)
